package ar.com.spsolutions.splibrary.utils;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashSet;
import java.util.Set;

import net.objectlab.kit.datecalc.common.DefaultHolidayCalendar;
import net.objectlab.kit.datecalc.common.HolidayCalendar;
import net.objectlab.kit.datecalc.common.HolidayHandlerType;
import net.objectlab.kit.datecalc.joda.LocalDateCalculator;
import net.objectlab.kit.datecalc.joda.LocalDateKitCalculatorsFactory;

import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.joda.time.LocalTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

public final class DateUtil {
    public static class DateUtilException extends RuntimeException {

        private static final long serialVersionUID = 4346822965758830254L;

        public DateUtilException(final Throwable cause) {
            super(cause);
        }

    }

    private static HolidayCalendar<LocalDate> makeCalendar() {
        Set<LocalDate> holidays = parseHolidays();
        HolidayCalendar<LocalDate> calendar = new DefaultHolidayCalendar<LocalDate>(holidays, new LocalDate(
                "2000-01-01"), new LocalDate("2099-12-31"));
        LocalDateKitCalculatorsFactory.getDefaultInstance().registerHolidays("AR", calendar);
        return calendar;
    }

    public static LocalDate getLaboralDate(final String date) {
        return getLaboralDate(new LocalDate(date));
    }

    public static LocalDate getLaboralDate(final DateTime date) {
        return getLaboralDate(new LocalDate(date));
    }

    public static LocalDate getLaboralDate(final LocalDate date) {
        LocalDateCalculator calculator = LocalDateKitCalculatorsFactory.getDefaultInstance().getDateCalculator("AR",
                HolidayHandlerType.FORWARD);
        return calculator.setCurrentBusinessDate(date);
    }

    private static Set<LocalDate> parseHolidays() {
        InputStream stream = ResourcesUtil.findResourceAsStream("holidays.cfg");
        Set<LocalDate> holidays = new HashSet<LocalDate>();
        try {
            byte[] buffer = new byte[stream.available()];
            stream.read(buffer);
            String holidaysString = new String(buffer);
            String[] holidayStr = holidaysString.split(",");
            DateTimeFormatter builder = DateTimeFormat.forPattern("dd/MM/yyyy");
            for (String holiday : holidayStr) {
                if (!holiday.isEmpty()) {
                    DateTime builded = builder.parseDateTime(holiday.trim());
                    holidays.add(new LocalDate(builded));
                }
            }
            return holidays;
        } catch (IOException e) {
            throw new DateUtilException(e);
        }
    }

    private DateUtil() {
        makeCalendar();
    }

    public static DateTime toDateTime(final LocalDate laboralDate) {
        return laboralDate.toDateTime(new LocalTime());
    }

    public static String format(final DateTime date) {
        return date.toString("dd/MM/yyyy");
    }
}
